﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfPaintPolygon
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 10; i < PolyBorder.Width; i += 10)
            {
                Line line = new Line();
                line.Stroke = Brushes.Silver;
                line.X2 = line.X1 = i;
                line.Y1 = 0;
                line.Y2 = PolyBorder.Height;
                PolyCanvas.Children.Add(line);
            }

            for (int i = 10; i < PolyBorder.Height; i += 10)
            {
                Line line = new Line();
                line.Stroke = Brushes.Silver;
                line.Y2 = line.Y1 = i;
                line.X1 = 0;
                line.X2 = PolyBorder.Width;
                PolyCanvas.Children.Add(line);
            }
        }

        #region Canvas methods

        /// TODO udelat hezci!
        Polyline poly;
        Line line;

        private void PolyCanvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // var point = e.GetPosition(PolyCanvas);
            var point = new Point((int)e.GetPosition(PolyCanvas).X, (int)e.GetPosition(PolyCanvas).Y);
            if (!canMouseDown) return;
            if (line == null)
            {
                line = new Line();
                line.Stroke = Brushes.Red;
                line.StrokeThickness = 2.0;
                // pridano kvuli vystrelovani cary z 0,0 souradnice
                line.X2 = point.X;
                line.Y2 = point.Y;
                Canvas.SetZIndex(line, 99);

                PolyCanvas.Children.Add(line);
            }

            line.X1 = point.X;
            line.Y1 = point.Y;

            if (poly == null)
            {
                poly = new Polyline();
                Canvas.SetZIndex(poly, 1);
                poly.Stroke = Brushes.Red;
                poly.Fill = Brushes.Yellow;
                poly.StrokeThickness = 2.0;
                poly.Points.Add(point);
                PolyCanvas.Children.Add(poly);
            }
            else
            {
                if (e.RightButton == MouseButtonState.Pressed)
                {
                    PolyCanvas.Children.Remove(poly);

                    var polygon = new Polygon();
                    polygon.Stroke = Brushes.Red;
                    polygon.Fill = Brushes.Yellow;
                    polygon.StrokeThickness = 2.0;
                    polygon.Points = poly.Points;
                    Canvas.SetZIndex(polygon, 1);
                    PolyCanvas.Children.Add(polygon);

                    line = null;
                }
                else
                {
                    poly.Points.Add(point);
                }
            }
        }

        bool canMouseDown = true;
        private void PolyCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            var point = new Point((int)e.GetPosition(PolyCanvas).X, (int)e.GetPosition(PolyCanvas).Y);
            if (line != null)
            {
                line.X2 = point.X;
                line.Y2 = point.Y;
                line.Stroke = Brushes.Red;
                line.StrokeDashArray = null;
                canMouseDown = true;

                Point last = new Point();
                bool isFirst = true;
                Point line1 = new Point(line.X1, line.Y1);
                foreach (Point p in poly.Points)
                {
                    if (!isFirst)
                    {
                        Point intersect;
                        if (ClippingEar.LineIntersect(last, p, line1, point, out intersect))
                        {
                            if (intersect != p && intersect != last && intersect != line1 && intersect != point)
                            {
                                line.Stroke = Brushes.Aqua;
                                line.StrokeDashArray = DoubleCollection.Parse("4 4");
                                canMouseDown = false;
                            }
                        }
                    }
                    else
                    {
                        isFirst = false;
                    }
                    last = p;
                }
            }
        }

        private void PolyCanvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (poly != null)
            {
                PointsBlock.Text = poly.Points.ToString();
            }
        }

        #endregion

        #region Buttons

        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
            PointsBlock.Text = string.Empty;
            List<UIElement> list = new List<UIElement>();
            foreach (UIElement ele in PolyCanvas.Children)
            {
                if (ele is Polygon || ele is Polyline)
                {
                    list.Add(ele);
                }
            }

            foreach (UIElement item in list)
            {
                PolyCanvas.Children.Remove(item);
            }

            if (line != null && PolyCanvas.Children.Contains(line))
            {
                PolyCanvas.Children.Remove(line);
            }

            poly = null;
            line = null;
        }

        private void EarButton_Click(object sender, RoutedEventArgs e)
        {
            IList<Polygon> triangles = new List<Polygon>();

            foreach (var child in PolyCanvas.Children)
            {
                if (child is Polygon)
                {
                    Polygon poly = (Polygon)child;
                    IList<IList<Point>> coll = ClippingEar.Triangulate(poly.Points);
                    if (coll == null)
                    {
                        MessageBox.Show("Non-simple polygon!");
                        continue;
                    }
                    foreach (IList<Point> points in coll)
                    {
                        Polygon pol = new Polygon();
                        pol.Stroke = Brushes.Black;
                        pol.StrokeThickness = 1;
                        pol.Points = new PointCollection(points);
                        Canvas.SetZIndex(pol, 2);
                        triangles.Add(pol);
                    }
                }
            }

            foreach (var triangle in triangles)
            {
                PolyCanvas.Children.Add(triangle);
            }

        }

        #endregion
    }
}
